import { isAndroid } from "./UtilFun";

export default class IndexedDB {
    private dbName: string;
    private version: number;
    private db: IDBDatabase | null = null;
    private keyPath: string = 'id'; // 固定使用 'id' 作为主键

    constructor(dbName: string, version = 2) {
        this.dbName = dbName;
        this.version = version;
        this.db = null;
    }

    async openDB(storeName: string) {
        return new Promise((resolve, reject) => {
            const request = indexedDB.open(this.dbName, this.version);

            request.onupgradeneeded = (event) => {
                this.db = (event.target as IDBOpenDBRequest).result;

                if (!this.db.objectStoreNames.contains(storeName)) {
                    // 创建对象存储空间，使用 'id' 作为 keyPath 并启用自动递增
                    const objectStore = this.db.createObjectStore(storeName, {
                        keyPath: 'id',
                        autoIncrement: true
                    });
                    objectStore.createIndex('id', 'id', { unique: true });
                }
            };

            request.onsuccess = (event) => {
                this.db = (event.target as IDBOpenDBRequest).result;
                resolve(this.db);
            };

            request.onerror = (event) => {
                reject(`数据库打开失败: ${(event.target as IDBOpenDBRequest).result}`);
            };
        });
    }

    checkDB(): boolean {
        if (!this.db) {
            console.error('数据库未打开或未初始化');
            return false;
        }
        return true;
    }

    // 添加数据（自动分配 id）
    async addData(storeName: string, data: any): Promise<number> {
        return new Promise((resolve, reject) => {
            if (!this.checkDB()) {
                reject('数据库未打开或未初始化');
                return;
            }

            // 移除传入数据中可能存在的 id 字段，让数据库自动分配
            const cleanData = { ...data };
            delete cleanData.id;

            console.log('添加数据:', storeName, cleanData,);


            const transaction = this.db!.transaction([storeName], 'readwrite');
            const objectStore = transaction.objectStore(storeName);
            const request = objectStore.add(cleanData);

            request.onsuccess = () => {
                resolve(request.result as number); // 返回分配的 id
                console.log('数据添加成功！分配的 ID:', request.result);
            };

            request.onerror = (event) => {
                reject(`添加数据失败: ${(event.target as IDBOpenDBRequest).error}`);
            };
        });
    }

    // 获取数据（通过 id）
    async getData(storeName: string, id: IDBValidKey) {
        return new Promise((resolve, reject) => {
            if (!this.checkDB()) {
                reject('数据库未打开或未初始化');
                return;
            }

            const transaction = this.db!.transaction([storeName], 'readonly');
            const objectStore = transaction.objectStore(storeName);
            const request = objectStore.get(id);

            request.onsuccess = () => {
                resolve(request.result);
            };

            request.onerror = (event) => {
                reject(`获取数据失败: ${(event.target as IDBOpenDBRequest).error}`);
            };
        });
    }

    // 更新数据（通过 id）
    async updateData(storeName: string, id: IDBValidKey, Data: any) {
        console.log('IndexedDB更新数据:', storeName, id, Data);

        return new Promise(async (resolve, reject) => {
            if (!this.checkDB()) {
                reject('数据库未打开或未初始化');
                return;
            }

            const objectStore = this.db!
                .transaction([storeName], "readwrite")
                .objectStore(storeName);
            const request = objectStore.get(id);


            request.onerror = (event) => {
                // 错误处理！
                reject(`获取数据失败: ${(event.target as IDBOpenDBRequest).error}`);
                return;
            };
            request.onsuccess = (event) => {
                console.log(event);

                // const data = (event.target as IDBRequest).result;
                // console.log(data);

                // const newData = { ...data, ...Data };
                // console.log(newData);

                // 把更新过的对象放回数据库。
                // const requestUpdate = objectStore.put(newData);
                const requestUpdate = objectStore.put(Data);
                requestUpdate.onerror = (event) => {
                    // 对错误进行处理
                    reject(`更新数据失败: ${(event.target as IDBOpenDBRequest).error}`);
                };
                requestUpdate.onsuccess = (event) => {
                    // 成功，数据已更新！
                    resolve(requestUpdate.result);
                    console.log('数据更新成功！');
                };
            };

            // const transaction = this.db!.transaction([storeName], 'readwrite');
            // const objectStore = transaction.objectStore(storeName);
            // const request = objectStore.get(id);

            // request.onerror = (event) => {
            //     reject(`获取数据失败: ${(event.target as IDBOpenDBRequest).error}`);
            //     return;
            // };

            // request.onsuccess = (event) => {
            //     const existingData = (event.target as IDBRequest).result;
            //     if (!existingData) {
            //         reject('数据不存在');
            //         return;
            //     }

            //     // 合并数据并确保 id 不被修改
            //     const newData = { ...existingData, ...data };
            //     newData.id = id; // 保证 id 不变


            //     console.log('更新数据:', storeName, newData);


            //     const updateRequest = objectStore.put(newData);
            //     updateRequest.onerror = (event) => {
            //         reject(`更新数据失败: ${(event.target as IDBOpenDBRequest).error}`);
            //     };
            //     updateRequest.onsuccess = (event) => {
            //         resolve(updateRequest.result);
            //         console.log('数据更新成功！');
            //     };
            // };
        });
    }

    // 删除数据（通过 id）
    async deleteData(storeName: string, id: IDBValidKey) {
        return new Promise((resolve, reject) => {
            if (!this.checkDB()) {
                reject('数据库未打开或未初始化');
                return;
            }

            const transaction = this.db!.transaction([storeName], 'readwrite');
            const objectStore = transaction.objectStore(storeName);
            const request = objectStore.delete(id);

            request.onsuccess = () => {
                resolve(true);
            };

            request.onerror = (event) => {
                reject(`删除数据失败: ${(event.target as IDBOpenDBRequest).error}`);
            };
        });
    }

    // 获取所有数据
    async getAllData(storeName: string) {
        return new Promise((resolve, reject) => {
            if (!this.checkDB()) {
                reject('数据库未打开或未初始化');
                return;
            }

            const transaction = this.db!.transaction([storeName], 'readonly');
            const objectStore = transaction.objectStore(storeName);
            const request = objectStore.getAll();

            request.onsuccess = () => {
                resolve(request.result);
            };

            request.onerror = (event) => {
                reject(`获取所有数据失败: ${(event.target as IDBOpenDBRequest).error}`);
            };
        });
    }
    async getAllStoreNames(): Promise<string[]> {
        if (!this.db) {
            // 如果数据库未打开，尝试打开它
            await this.openDB('temp')  // 需要传入参数
        }
        return Array.from(this.db!.objectStoreNames);
    }

    // 导出数据库
    async exportDB() {
        try {
            // 获取所有存储空间名称
            const storeNames = Array.from(this.db!.objectStoreNames);
            const exportData: Record<string, any[]> = {};

            // 遍历每个存储空间导出数据
            for (const storeName of storeNames) {
                const data = await this.getAllData(storeName);
                exportData[storeName] = data as any[];
            }

            // 转换为 JSON 字符串
            const jsonData = JSON.stringify(exportData, null, 2);

            // 创建下载链接
            if (isAndroid()) {
                window.ClosetAndroid.exportJsonDB(jsonData, "exported_data.json");
            } else {
                const blob = new Blob([jsonData], { type: 'application/json' });
                const url = URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = `database_export_${new Date().toISOString().slice(0, 10)}.json`;
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
                URL.revokeObjectURL(url);
            }
            console.log('数据库导出成功');
        } catch (error) {
            console.error('数据库导出失败:', error);
        }
    }

    // 清空指定存储空间的所有数据
    async clearStore(storeName: string) {
        return new Promise((resolve, reject) => {
            if (!this.checkDB()) {
                reject('数据库未打开或未初始化');
                return;
            }

            const transaction = this.db!.transaction([storeName], 'readwrite');
            const objectStore = transaction.objectStore(storeName);
            const request = objectStore.clear();

            request.onsuccess = () => {
                resolve(true);
                console.log(`${storeName} 存储空间数据已清空`);
            };

            request.onerror = (event) => {
                reject(`清空数据失败: ${(event.target as IDBOpenDBRequest).error}`);
            };
        });
    }

    // 清空所有存储空间的数据
    async clearAllStores() {
        try {
            const storeNames = Array.from(this.db!.objectStoreNames);
            for (const storeName of storeNames) {
                await this.clearStore(storeName);
            }
            console.log('所有存储空间数据已清空');
        } catch (error) {
            console.error('清空所有数据失败:', error);
        }
    }
    // 关闭数据库
    closeDB() {
        if (this.db) {
            this.db.close();
            this.db = null;
        }
    }
}